package com.acme.bankapp;

import java.io.IOException;

import com.acme.bankapp.domain.account.Account;
import com.acme.bankapp.domain.account.CheckingAccount;
import com.acme.bankapp.domain.account.SavingAccount;
import com.acme.bankapp.domain.bank.Bank;
import com.acme.bankapp.domain.client.Client;
import com.acme.bankapp.domain.client.Gender;
import com.acme.bankapp.exception.ClientExistsException;
import com.acme.bankapp.exception.NotEnoughFundsException;
import com.acme.bankapp.service.bank.BankService;

public class BankApplicationTest {
    protected static final String CLIENT_1_NAME = "Petrov";
    protected static final String CLIENT_2_NAME = "Pugacheva";
    protected static final String CLIENT_3_NAME = "Kirkorov";
    protected static final String CLIENT_4_NAME = "Pirozhkov";
    protected static final String CLIENT_5_NAME = "Medvedev";
    protected static final Client[] clients;
    protected static final Account[] accounts;
    static {
	accounts = new Account[] { new SavingAccount(140000.20),
		new SavingAccount(2662.72),
		new CheckingAccount(9523.14, 13000), new SavingAccount(0.2),
		new CheckingAccount(0.0, 95000.0) };
	clients = new Client[] {
		new Client(CLIENT_1_NAME, Gender.MALE, accounts[0]),
		new Client(CLIENT_2_NAME, Gender.FEMALE, accounts[1]),
		new Client(CLIENT_3_NAME, Gender.MALE, accounts[2]),
		new Client(CLIENT_4_NAME, Gender.MALE, accounts[3]),
		new Client(CLIENT_5_NAME, Gender.MALE, accounts[4]) };
    }
    
    public static void main(String[] args) {
	BankService bankService = createTestBankService();
	bankService.printBalance();
	bankService.printMaximumAmountToWithdraw();
    }

    public static BankService createTestBankService() {
	BankService bankService = new BankService(new Bank());
	initBank(bankService);
	modifyBank(bankService);
	try {
	    bankService.saveBank();
	} catch (IOException e) {
	    e.printStackTrace();
	}
	return bankService;
    }

    public static void modifyBank(final BankService bankservice) {
	Account account = getClientAccount(bankservice, CLIENT_5_NAME);
	account.deposit(1000000.00);
	account = getClientAccount(bankservice, CLIENT_1_NAME);
	try {
	    account.withdraw(140000.00);
	} catch (NotEnoughFundsException e) {
	    System.err.println(e.getMessage());
	}
	account = getClientAccount(bankservice, CLIENT_5_NAME);
	try {
	    account.withdraw(140000.00);
	} catch (NotEnoughFundsException e) {
	    System.err.println(e.getMessage());
	}
	account = getClientAccount(bankservice, CLIENT_2_NAME);
	try {
	    account.withdraw(1940000.00);
	} catch (NotEnoughFundsException e) {
	    System.err.println(e.getMessage());
	}
    }

    private static Account getClientAccount(final BankService bankservice,
	    final String clientName) {
	Client client = bankservice.getClient(clientName);
	return client.getAccount();
    }

    static void initBank(final BankService bankservice) {
	for (Client client : clients) {
	    try {
		bankservice.addClient(client);
	    } catch (ClientExistsException e) {
		System.err.println(e.getMessage());
	    } catch (IOException e) {
		e.printStackTrace();
	    }
	}
    }
}
